package co.gov.medellin.ssti.sub.paoyer.administration.dao;

import java.sql.BatchUpdateException;
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.sql.PreparedStatement;

import co.gov.medellin.ssti.sub.paoyer.administration.model.vo.UserGroupOptionVO;

/**
 * DAO para crear, consultar , borrar y actualizar registros en la tabla
 * TCS_OPCIONES_GRUPO.
 * 
 * @author Rene.Rangel@consultsoft.com
 * @version 1.0
 */

public class UserGroupOptionDAO {
	/**
	 * Conexion a la base de datos.
	 */
	private Connection conn = null;

	/**
	 * Constructor que inicializa la conexion con la base de datos.
	 * 
	 * @param conn
	 *            Conexion con la base de datos.
	 */

	public UserGroupOptionDAO(Connection conn) {
		this.conn = conn;
	}

	/**
	 * Consulta un grupo de registros de la tabla TCS_OPCIONES_GRUPO a partir de
	 * las condiciones que vienen en el Value Object
	 * 
	 * @param UserGroupOptionVO
	 *            Value Object con las condiciones a tener encuenta.
	 * 
	 * @return Collection Arreglo de registros retornados de la consulta.
	 */
	public Collection<UserGroupOptionVO> findUserGroupOptionByCriterea(
			UserGroupOptionVO criterea) throws SQLException {

		/**
		 * La busqueda se hace sobre las tablas Tcs_Opciones_Grupo , Tcs_Opcion
		 * y Tcs_Grupo_Usuario con el objeto de traer el nombre de la opcion y
		 * el grupo de usuario asociado por cada registro
		 */

		String query = "SELECT opgr.*, grus.nombre grupo_usuario, opci.nombre opcion "
				+ "FROM tcs_grupo_usuario grus, tcs_opciones_grupo opgr, "
				+ "tcs_opcion opci";

		String filters = "";

		// Filtro por Descripcion
		if ((criterea.getDescription() != null)
				&& !(criterea.getDescription().equalsIgnoreCase(""))) {
			filters = filters + " AND UPPER(opgr.descripcion) LIKE '%"
					+ criterea.getDescription().toUpperCase() + "%' ";
		}

		// Filtro por Nombre
		if ((criterea.getOptionName() != null)
				&& !(criterea.getOptionName().equalsIgnoreCase(""))) {
			filters = filters + " AND UPPER(opci.nombre) LIKE '%"
					+ criterea.getOptionName().toUpperCase() + "%' ";
		}

		// Filtro por Indicador de Consulta
		if ((criterea.getAllowQuery() != null)
				&& !(criterea.getAllowQuery().equals(""))) {
			filters = filters + " AND opgr.consultar = '"
					+ criterea.getAllowQuery() + "'";
		}

		// Filtro por Indicador de Actualizacion
		if ((criterea.getAllowUpdate() != null)
				&& !(criterea.getAllowUpdate().equals(""))) {
			filters = filters + " AND opgr.actualizar = '"
					+ criterea.getAllowUpdate() + "'";
		}

		// Filtro por Indicacion de Insercion
		if ((criterea.getAllowInsert() != null)
				&& !(criterea.getAllowInsert().equals(""))) {
			filters = filters + " AND opgr.insertar = '"
					+ criterea.getAllowInsert() + "'";
		}

		// Filtro por Indicador de Borrado
		if ((criterea.getAllowDelete() != null)
				&& !(criterea.getAllowDelete().equals(""))) {
			filters = filters + " AND opgr.borrar = '"
					+ criterea.getAllowDelete() + "'";
		}

		// Filtro por Codigo de Grupo Usuarios
		if (criterea.getUserGroupCode() != null) {
			filters = filters + " AND opgr.gus_codigo = "
					+ criterea.getUserGroupCode();
		}

		// Filtro por Codigo de Opcion
		if (criterea.getOptionCode() != null) {
			filters = filters + " AND opgr.opc_codigo = "
					+ criterea.getOptionCode();
		}

		query = query + " WHERE opci.codigo = opgr.opc_codigo and "
				+ "grus.codigo = opgr.gus_codigo and rownum<51 ";

		// Si hay filtros, entonces armar la clausula WHERE
		if (!filters.equals("")) {
			query = query + filters;
		}
		Statement stm = null;
		ResultSet rst = null;
		ArrayList<UserGroupOptionVO> userGroupOptions = new ArrayList<UserGroupOptionVO>();

		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			UserGroupOptionVO userGroupOption = new UserGroupOptionVO();
			userGroupOption.setCode(new Long(rst.getLong("codigo")));
			userGroupOption.setDescription(rst.getString("descripcion"));
			userGroupOption.setWebUserCrea(rst.getString("usuario_crea"));
			userGroupOption.setWebClientCrea(rst.getString("terminal_crea"));
			userGroupOption.setWebUserModif(rst.getString("usuario_modifica"));
			userGroupOption.setWebClientModif(rst
					.getString("terminal_modifica"));
			userGroupOption.setAllowQuery(rst.getString("consultar"));
			userGroupOption.setAllowUpdate(rst.getString("actualizar"));
			userGroupOption.setAllowInsert(rst.getString("insertar"));
			userGroupOption.setAllowDelete(rst.getString("borrar"));
			userGroupOption
					.setUserGroupCode(new Long(rst.getLong("gus_codigo")));
			userGroupOption.setUserGroupName(rst.getString("grupo_usuario"));
			userGroupOption.setOptionCode(new Long(rst.getLong("opc_codigo")));
			userGroupOption.setOptionName(rst.getString("opcion"));

			userGroupOptions.add(userGroupOption);
		}

		stm.close();

		return userGroupOptions;
	}

	public boolean asociateOptionToUserGroup(UserGroupOptionVO criterea)
			throws SQLException {

		// conn.setAutoCommit(false);
		Statement stm = conn.createStatement();
		String strSQL = "";
		for (int i = 0; i < criterea.getOptionList().length; i++) {
			strSQL = ""
					+ "INSERT INTO tcs_opciones_grupo (codigo, descripcion, usuario_crea, "
					+ "terminal_crea, usuario_modifica, terminal_modifica, consultar, "
					+ "actualizar, insertar, borrar, gus_codigo, opc_codigo) "
					+ "VALUES(scs_opciones_grupo.nextval," + "''," + "'"
					+ criterea.getWebUserCrea().toUpperCase() + "','WEB="
					+ criterea.getWebClientCrea().toUpperCase() + "','"
					+ criterea.getWebUserModif() + "','WEB="
					+ criterea.getWebClientModif() + "','S','S','S','S',"
					+ criterea.getUserGroupCode() + ","
					+ criterea.getOptionList()[i] + ")";

			stm.addBatch(strSQL);
		}

		try {
			int[] updateCounts = stm.executeBatch();
			// conn.commit();
			// conn.setAutoCommit(true);
			stm.close();

		} catch (BatchUpdateException b) {

			/*
			 * System.err.println("----BatchUpdateException----");
			 * System.err.println("SQLState:  " + b.getSQLState());
			 * System.err.println("Message:  " + b.getMessage());
			 * System.err.println("Vendor:  " + b.getErrorCode());
			 * System.err.println("Update counts:  ");
			 */

			int[] updateCounts = b.getUpdateCounts();
			for (int i = 0; i < updateCounts.length; i++) {
				System.err.print(updateCounts[i] + "   ");
			}
		}

		return true;
	}

	public Collection<UserGroupOptionVO> findNotAsociatedOptionByCriterea(
			UserGroupOptionVO criterea) throws SQLException {

		String query = "";

		query = "SELECT op.*"
				+ " FROM  tcs_opcion op  where op.codigo not in "
				+ "( select gru.opc_codigo FROM tcs_opciones_grupo  gru where gru.gus_codigo="
				+ criterea.getUserGroupCode() + ") and  rownum<51";

		String filters = "";

		// Filtro por Descripcion
		if ((criterea.getDescription() != null)
				&& !(criterea.getDescription().equalsIgnoreCase(""))) {
			filters = filters + " AND UPPER(op.descripcion) LIKE '%"
					+ criterea.getDescription().toUpperCase() + "%' ";
		}

		// Filtro por Nombre
		if ((criterea.getOptionName() != null)
				&& !(criterea.getOptionName().equalsIgnoreCase(""))) {
			filters = filters + " AND UPPER(op.nombre) LIKE '%"
					+ criterea.getOptionName().toUpperCase() + "%' ";
		}

		// Filtro por Codigo de Opcion
		if (criterea.getOptionCode() != null) {
			filters = filters + " AND op.opc_codigo = "
					+ criterea.getOptionCode();
		}

		// Si hay filtros, entonces armar la clausula WHERE
		if (!filters.equals("")) {
			query = query + filters;
		}
		Statement stm = null;
		ResultSet rst = null;
		ArrayList<UserGroupOptionVO> userGroupOptions = new ArrayList<UserGroupOptionVO>();

		stm = conn.createStatement();
		rst = stm.executeQuery(query);

		while (rst.next()) {
			UserGroupOptionVO userGroupOption = new UserGroupOptionVO();

			userGroupOption.setDescription(rst.getString("descripcion"));
			userGroupOption.setOptionCode(new Long(rst.getLong("codigo")));
			userGroupOption.setOptionName(rst.getString("nombre"));

			userGroupOptions.add(userGroupOption);
		}

		stm.close();

		return userGroupOptions;
	}

	/**
	 * Crea un nuevo registro en la tabla TCS_OPCIONES_GRUPO.
	 * 
	 * @param UserGroupOptionVO
	 *            Value Object con el registro que se va a Crear.
	 * 
	 * @return UserGroupOptionVO Registro creado.
	 * 
	 */
	public UserGroupOptionVO createUserGroupOption(
			UserGroupOptionVO newUserGroupOption) throws SQLException {

		String strSQL = "";
		boolean result = false;
		PreparedStatement ps = null;
		strSQL = ""
				+ "INSERT INTO tcs_opciones_grupo (codigo, descripcion, usuario_crea, "
				+ "terminal_crea, usuario_modifica, terminal_modifica, consultar, "
				+ "actualizar, insertar, borrar, gus_codigo, opc_codigo) "
				+ "VALUES(scs_opciones_grupo.nextval,?,?,?,?,?,?,?,?,?,?,?)";

		ps = conn.prepareStatement(strSQL);
		ps.setString(1, newUserGroupOption.getDescription().toUpperCase());
		ps.setString(2, newUserGroupOption.getWebUserCrea().toUpperCase());
		ps.setString(3, "WEB="
				+ newUserGroupOption.getWebClientCrea().toUpperCase());
		ps.setString(4, newUserGroupOption.getWebUserModif().toUpperCase());
		ps.setString(5, "WEB="
				+ newUserGroupOption.getWebClientModif().toUpperCase());
		ps.setString(6, newUserGroupOption.getAllowQuery().toUpperCase());
		ps.setString(7, newUserGroupOption.getAllowUpdate().toUpperCase());
		ps.setString(8, newUserGroupOption.getAllowInsert().toUpperCase());
		ps.setString(9, newUserGroupOption.getAllowDelete().toUpperCase());
		ps.setLong(10, newUserGroupOption.getUserGroupCode().longValue());
		ps.setLong(11, newUserGroupOption.getOptionCode().longValue());
		result = ps.execute();

		if (result) {
			Statement stm = conn.createStatement();
			ResultSet rst = stm
					.executeQuery("SELECT scs_opciones_grupo.currval FROM dual");
			if (rst.next()) {
				newUserGroupOption.setCode(new Long(rst.getLong(1)));
			}
			stm.close();
			rst.close();
		}

		ps.close();

		return newUserGroupOption;
	}

	/**
	 * Actualiza un registro en la tabla TCS_OPCIONES_GRUPO por la llave
	 * primaria.
	 * 
	 * @param UserGroupOptionVO
	 *            Value Object con el registro que se va a modificar.
	 * 
	 * @return UserGroupOptionVO Registro modificado.
	 * 
	 */
	public UserGroupOptionVO updateUserGroupOption(
			UserGroupOptionVO userGroupOption) throws SQLException {

		String strSQL = "UPDATE tcs_opciones_grupo" + "SET descripcion = ?,"
				+ "usuario_modifica = ?," + "terminal_modifica = ?,"
				+ "consultar = ?," + "actualizar = ?," + "insertar = ?,"
				+ "borrar = ?," + "gus_codigo = ?," + "opc_codigo = ?"
				+ "WHERE codigo = ?;";
		PreparedStatement ps = conn.prepareStatement(strSQL);

		ps.setString(1, userGroupOption.getDescription().toUpperCase());
		ps.setString(2, userGroupOption.getWebUserModif().toUpperCase());
		ps.setString(3, "WEB="
				+ userGroupOption.getWebClientModif().toUpperCase());
		ps.setString(4, userGroupOption.getAllowQuery().toUpperCase());
		ps.setString(5, userGroupOption.getAllowUpdate().toUpperCase());
		ps.setString(6, userGroupOption.getAllowInsert().toUpperCase());
		ps.setString(7, userGroupOption.getAllowDelete().toUpperCase());
		ps.setLong(8, userGroupOption.getUserGroupCode().longValue());
		ps.setLong(9, userGroupOption.getOptionCode().longValue());
		ps.setLong(10, userGroupOption.getCode().longValue());

		int updates = ps.executeUpdate();

		if (updates == 0) {
			return null;
		}

		ps.close();

		return userGroupOption;

	}

	/**
	 * Borra un registro de la tabla TCS_OPCIONES_GRUPO por la llave primaria.
	 * 
	 * @param UserGroupOptionVO
	 *            Value Object con el registro que se va a borrar.
	 * 
	 * @return boolean Indicador de exito de la operacion de borrado
	 */
	public boolean deleteUserGroupOption(UserGroupOptionVO userGroupOption)
			throws SQLException {

		String strSQL = "DELETE tcs_opciones_grupo " + "WHERE  codigo = ?";
		PreparedStatement ps = conn.prepareStatement(strSQL);
		ps.setLong(1, userGroupOption.getCode().longValue());
		boolean deletes = ps.execute();
		ps.close();
		return deletes;
	}

}